package com.wzb.mybatisplus.bitaction.electrumaction;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class WorkingElectrumClient {

    private static final String ELECTRUM_SERVER_HOST = "127.0.0.1";
    private static final int ELECTRUM_SSL_PORT = 50001;

    private SSLSocket socket;
    private BufferedReader reader;
    private BufferedWriter writer;
    private ObjectMapper mapper;
    private int requestId = 0;

    public static void main(String[] args) {
        WorkingElectrumClient client = new WorkingElectrumClient();

        try {
            if (client.connect()) {
                String bitcoinAddress = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa";

                // 测试连接
                String version = client.getServerVersion();
                System.out.println("服务器版本: " + version);

                // 查询余额（使用已知的有效脚本哈希进行测试）
                String balance = client.getBalance(bitcoinAddress);
                System.out.println("余额结果: " + balance);

                client.disconnect();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public boolean connect() {
        try {
            System.out.println("正在连接到 " + ELECTRUM_SERVER_HOST + ":" + ELECTRUM_SSL_PORT);

            SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
            socket = (SSLSocket) factory.createSocket(ELECTRUM_SERVER_HOST, ELECTRUM_SSL_PORT);

            // 配置 SSL
            socket.setEnabledProtocols(new String[]{"TLSv1.2", "TLSv1.3"});
            socket.setSoTimeout(30000); // 30秒超时

            InputStream inputStream = socket.getInputStream();
            OutputStream outputStream = socket.getOutputStream();

            reader = new BufferedReader(new InputStreamReader(inputStream));
            writer = new BufferedWriter(new OutputStreamWriter(outputStream));
            mapper = new ObjectMapper();

            System.out.println("SSL 连接建立成功");
            return true;

        } catch (Exception e) {
            System.err.println("连接失败: " + e.getMessage());
            return false;
        }
    }

    /**
     * 改进的读取方法 - 解决 readLine() 阻塞问题
     */
    private String readResponse() throws IOException {
        StringBuilder responseBuilder = new StringBuilder();
        char[] buffer = new char[1024];
        int bytesRead;
        long startTime = System.currentTimeMillis();

        System.out.println("开始读取响应...");

        while (true) {
            // 检查超时
            if (System.currentTimeMillis() - startTime > 25000) {
                System.err.println("读取响应超时");
                return null;
            }

            // 检查是否有数据可读
            if (reader.ready()) {
                bytesRead = reader.read(buffer);
                if (bytesRead == -1) {
                    break; // 流结束
                }

                String chunk = new String(buffer, 0, bytesRead);
                responseBuilder.append(chunk);
                System.out.println("读取到数据块: " + chunk);

                // 检查是否收到完整JSON（包含右花括号）
                String currentResponse = responseBuilder.toString();
                if (currentResponse.trim().endsWith("}")) {
                    System.out.println("检测到完整JSON响应");
                    break;
                }
            } else {
                // 没有数据可读，短暂等待
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }

        String response = responseBuilder.toString().trim();
        System.out.println("完整响应: " + response);
        return response.isEmpty() ? null : response;
    }

    /**
     * 发送请求并获取响应
     */
    private String sendRequest(String method, ArrayNode params) throws IOException {
        ObjectNode request = mapper.createObjectNode();
        request.put("id", requestId);
        request.put("method", method);
        request.set("params", params);
        request.put("jsonrpc", "2.0");

        String requestString = request.toString() + "\n";
        System.out.println("发送请求 ID " + requestId + ": " + requestString);

        // 发送请求
        writer.write(requestString);
        writer.flush();

        // 读取响应
        String response = readResponse();

        requestId++; // 只在成功发送后递增ID

        return response;
    }

    /**
     * 获取服务器版本 - 测试连接
     */
    public String getServerVersion() {
        try {
            String response = sendRequest("server.version",
                    mapper.createArrayNode()
                            .add("java-electrum-client")
                            .add("1.4.2"));

            if (response != null) {
                JsonNode root = mapper.readTree(response);
                JsonNode result = root.get("result");
                if (result != null && result.isArray() && result.size() > 0) {
                    return result.get(0).asText();
                }
            }
            return "获取版本失败: " + response;
        } catch (Exception e) {
            return "获取版本异常: " + e.getMessage();
        }
    }

    /**
     * 查询余额
     */
    public String getBalance(String address) {
        try {
            // 使用一个测试用的脚本哈希
            String testScriptHash = "8b01df4e368ea28f8dc0423bcf7a4923e3a12d307c875e47a0cfbf90b5c39161";

            String response = sendRequest("blockchain.scripthash.get_balance",
                    mapper.createArrayNode().add(testScriptHash));

            if (response == null) {
                return "无响应";
            }

            JsonNode root = mapper.readTree(response);
            JsonNode result = root.get("result");

            if (result != null && result.isObject()) {
                long confirmed = result.get("confirmed").asLong();
                long unconfirmed = result.get("unconfirmed").asLong();
                return String.format("确认: %.8f BTC, 未确认: %.8f BTC",
                        confirmed / 100000000.0, unconfirmed / 100000000.0);
            } else {
                JsonNode error = root.get("error");
                return "错误: " + (error != null ? error.toString() : "未知错误");
            }
        } catch (Exception e) {
            return "异常: " + e.getMessage();
        }
    }

    public void disconnect() {
        try {
            if (reader != null) reader.close();
            if (writer != null) writer.close();
            if (socket != null) socket.close();
            System.out.println("连接已断开");
        } catch (IOException e) {
            System.err.println("断开连接时出错: " + e.getMessage());
        }
    }
}
